/**
 * File Info：com.mys.springboot.config.base.BaseService.java
 * Created Date：2017年5月15日 下午3:46:51
 * Created User: mys
 */
package com.mys.springboot.config.base;

import java.io.Serializable;
import java.util.List;

import javax.annotation.Resource;
import javax.persistence.EntityManager;

import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.Query;

/**
 * @description
 * 
 * @author mys
 * @version 1.0
 *
 */
public class BaseService<T, ID extends Serializable> {
	@Resource
	private BaseRepository<T, ID> repository;

	/**
	 * 获取Repostory对象
	 * 
	 * @CreatedDate 2017年5月15日 下午3:54:29
	 * @CreatedUser mys
	 * @Version 1.0
	 * @LastUpdateDate 2017年5月15日 下午3:54:29
	 * @LastUpdateUser mys
	 * @return
	 */
	public BaseRepository<T, ID> getRepository() {
		return this.repository;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.springframework.data.repository.CrudRepository#findAll()
	 */
	public List<T> findAll() {
		return this.getRepository().findAll();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.springframework.data.repository.PagingAndSortingRepository#findAll(
	 * org.springframework.data.domain.Sort)
	 */
	public List<T> findAll(Sort sort) {
		return this.getRepository().findAll(sort);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.springframework.data.repository.CrudRepository#findAll(java.lang.
	 * Iterable)
	 */
	public List<T> findAll(Iterable<ID> ids) {
		return this.getRepository().findAll(ids);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.springframework.data.repository.CrudRepository#save(java.lang.
	 * Iterable)
	 */
	public <S extends T> List<S> save(Iterable<S> entities) {
		return this.getRepository().save(entities);
	}

	/**
	 * Flushes all pending changes to the database.
	 */
	public void flush() {
		this.getRepository().flush();
	}

	/**
	 * Saves an entity and flushes changes instantly.
	 * 
	 * @param entity
	 * @return the saved entity
	 */
	public <S extends T> S saveAndFlush(S entity) {
		return this.getRepository().saveAndFlush(entity);
	}

	/**
	 * Deletes the given entities in a batch which means it will create a single
	 * {@link Query}. Assume that we will clear the
	 * {@link javax.persistence.EntityManager} after the call.
	 * 
	 * @param entities
	 */
	public void deleteInBatch(Iterable<T> entities) {
		this.getRepository().deleteInBatch(entities);
	}

	/**
	 * Deletes all entities in a batch call.
	 */
	public void deleteAllInBatch() {
		this.getRepository().deleteAllInBatch();
	}

	/**
	 * Returns a reference to the entity with the given identifier.
	 * 
	 * @param id
	 *            must not be {@literal null}.
	 * @return a reference to the entity with the given identifier.
	 * @see EntityManager#getReference(Class, Object)
	 */
	public T getOne(ID id) {
		return this.getRepository().getOne(id);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.springframework.data.repository.query.QueryByExampleExecutor#findAll(
	 * org.springframework.data.domain.Example)
	 */
	public <S extends T> List<S> findAll(Example<S> example) {
		return this.getRepository().findAll(example);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.springframework.data.repository.query.QueryByExampleExecutor#findAll(
	 * org.springframework.data.domain.Example,
	 * org.springframework.data.domain.Sort)
	 */
	public <S extends T> List<S> findAll(Example<S> example, Sort sort) {
		return this.getRepository().findAll(example, sort);
	}

	/**
	 * Returns a {@link Page} of entities meeting the paging restriction
	 * provided in the {@code Pageable} object.
	 * 
	 * @param pageable
	 * @return a page of entities
	 */
	public Page<T> findAll(Pageable pageable) {
		return this.getRepository().findAll(pageable);
	}

	/**
	 * Saves a given entity. Use the returned instance for further operations as
	 * the save operation might have changed the entity instance completely.
	 * 
	 * @param entity
	 * @return the saved entity
	 */
	public <S extends T> S save(S entity) {
		return this.getRepository().save(entity);
	}

	/**
	 * Retrieves an entity by its id.
	 * 
	 * @param id
	 *            must not be {@literal null}.
	 * @return the entity with the given id or {@literal null} if none found
	 * @throws IllegalArgumentException
	 *             if {@code id} is {@literal null}
	 */
	public T findOne(ID id) {
		return this.getRepository().findOne(id);
	}

	/**
	 * Returns whether an entity with the given id exists.
	 * 
	 * @param id
	 *            must not be {@literal null}.
	 * @return true if an entity with the given id exists, {@literal false}
	 *         otherwise
	 * @throws IllegalArgumentException
	 *             if {@code id} is {@literal null}
	 */
	public boolean exists(ID id) {
		return this.getRepository().exists(id);
	}

	/**
	 * Returns the number of entities available.
	 * 
	 * @return the number of entities
	 */
	public long count() {
		return this.getRepository().count();
	}

	/**
	 * Deletes the entity with the given id.
	 * 
	 * @param id
	 *            must not be {@literal null}.
	 * @throws IllegalArgumentException
	 *             in case the given {@code id} is {@literal null}
	 */
	public void delete(ID id) {
		this.getRepository().delete(id);
	}

	/**
	 * Deletes a given entity.
	 * 
	 * @param entity
	 * @throws IllegalArgumentException
	 *             in case the given entity is {@literal null}.
	 */
	public void delete(T entity) {
		this.getRepository().delete(entity);
	}

	/**
	 * Deletes the given entities.
	 * 
	 * @param entities
	 * @throws IllegalArgumentException
	 *             in case the given {@link Iterable} is {@literal null}.
	 */
	public void delete(Iterable<? extends T> entities) {
		this.getRepository().delete(entities);
	}

	/**
	 * Deletes all entities managed by the repository.
	 */
	public void deleteAll() {
		this.getRepository().deleteAll();
	}

	/**
	 * Returns a single entity matching the given {@link Example} or
	 * {@literal null} if none was found.
	 *
	 * @param example
	 *            can be {@literal null}.
	 * @return a single entity matching the given {@link Example} or
	 *         {@literal null} if none was found.
	 * @throws org.springframework.dao.IncorrectResultSizeDataAccessException
	 *             if the Example yields more than one result.
	 */
	public <S extends T> S findOne(Example<S> example) {
		return this.getRepository().findOne(example);
	}

	/**
	 * Returns a {@link Page} of entities matching the given {@link Example}. In
	 * case no match could be found, an empty {@link Page} is returned.
	 *
	 * @param example
	 *            can be {@literal null}.
	 * @param pageable
	 *            can be {@literal null}.
	 * @return a {@link Page} of entities matching the given {@link Example}.
	 */
	public <S extends T> Page<S> findAll(Example<S> example, Pageable pageable) {
		return this.getRepository().findAll(example, pageable);
	}

	/**
	 * Returns the number of instances matching the given {@link Example}.
	 *
	 * @param example
	 *            the {@link Example} to count instances for, can be
	 *            {@literal null}.
	 * @return the number of instances matching the {@link Example}.
	 */
	public <S extends T> long count(Example<S> example) {
		return this.getRepository().count(example);
	}

	/**
	 * Checks whether the data store contains elements that match the given
	 * {@link Example}.
	 *
	 * @param example
	 *            the {@link Example} to use for the existence check, can be
	 *            {@literal null}.
	 * @return {@literal true} if the data store contains elements that match
	 *         the given {@link Example}.
	 */
	public <S extends T> boolean exists(Example<S> example) {
		return this.getRepository().exists(example);
	}

}
